package com.itmumu.miniwechat.chat.websocket.netty;

import com.itmumu.miniwechat.chat.websocket.netty.ChatHandler;
import com.itmumu.miniwechat.chat.websocket.netty.HeartBeatHandler;
import com.itmumu.miniwechat.common.utils.RedisUtils;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class NettyWebSocketStarter implements Runnable {

    @Resource
    private ChatHandler chatHandler;


   private static EventLoopGroup bossGroup =  new NioEventLoopGroup(1);

   private static EventLoopGroup workerGroup = new NioEventLoopGroup();


    @Override
    public void     run() {
        try {
            ChannelFuture channelFuture = new ServerBootstrap()
                    .group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer() {

                        @Override
                        protected void initChannel(Channel channel) throws Exception {
                            // 对http协议支持，http编码器和解码器
                            channel.pipeline().addLast(new HttpServerCodec());
                            //聚合解码 httpRequest/htppContent/lastHttpContent到fullHttpRequest
                            channel.pipeline().addLast(new HttpObjectAggregator(65536));
                            // readerIdleTime  读超时事件 即测试段一定事件内未接收到被测试段消息
                            // writerIdleTime  为写超时时间 即测试端一定时间内想被测试端发送消息
                            //allIdleTime  所有类型的超时时间
                            channel.pipeline().addLast(new IdleStateHandler(60, 0, 0, TimeUnit.SECONDS));
                            channel.pipeline().addLast(new HeartBeatHandler());
                            //将http协议升级为ws协议，对websocket支持
                            channel.pipeline().addLast(new WebSocketServerProtocolHandler("/ws", null, true, 64 * 1024, true, true, 10000L));
                            channel.pipeline().addLast(chatHandler);
                        }
                    })
                    .bind(5052).sync();

            channelFuture.channel().closeFuture().addListener((ChannelFutureListener) channelFuture1 -> {
                log.debug("处理关闭之后的操作");
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            });
            log.info("netty启动成功！！！");
        } catch (InterruptedException e) {
            log.error("启动netty失败, {}", e);
        }
    }
}
